package com.example.taobaounion.presenter.impl;

import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.example.taobaounion.model.Api;
import com.example.taobaounion.model.domain.Histories;
import com.example.taobaounion.model.domain.SearchRecommend;
import com.example.taobaounion.model.domain.SearchResult;
import com.example.taobaounion.presenter.ISearchPresenter;
import com.example.taobaounion.utils.JsonCacheUtil;
import com.example.taobaounion.utils.RetrofitUtils;
import com.example.taobaounion.utils.ToastUtils;
import com.example.taobaounion.view.callback.ISearchViewCallback;

import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;

public class SearchPresenter implements ISearchPresenter {

    private static final int DEFAULT_PAGE = 0;
    private static final int historiesMaxSize = 10;

    private static final String KEY_HISTORY = "key_history";


    private final Api mApi;
    private ISearchViewCallback mViewCallback;

    private int mCurrentPage = DEFAULT_PAGE;
    private String mCurrentKeyword;
    private boolean mIsLoadMoreFlag;
    private JsonCacheUtil mJsonCacheUtil;


    public SearchPresenter() {

        mIsLoadMoreFlag = false;
        mCurrentKeyword = null;

        Retrofit retrofit = RetrofitUtils.getInstance().getRetrofit();

        mApi = retrofit.create(Api.class);
        mJsonCacheUtil = JsonCacheUtil.getInstance();
    }

    @Override
    public void getHistories() {
        Histories histories = mJsonCacheUtil.getValue(KEY_HISTORY, Histories.class);
        if (histories != null) {
            mViewCallback.onHistoriesLoaded(histories.getHistories());
        } else {
            mViewCallback.onHistoriesLoaded(null);
        }
    }

    @Override
    public void delHistories() {
        mJsonCacheUtil.delCache(KEY_HISTORY);

        if (mViewCallback != null) {
            mViewCallback.onHistoriesDeleted();
        }
    }

    /**
     * 添加历史记录
     *
     * @param history 历史搜索记录
     */
    private void saveHistory(String history) {

        Histories histories = mJsonCacheUtil.getValue(KEY_HISTORY, Histories.class);

        List<String> historiesList = null;
        if (histories != null) {
            historiesList = histories.getHistories();

            historiesList.remove(history);
        }

        if (historiesList == null) {
            historiesList = new ArrayList<>();
        }

        if (histories == null) {
            histories = new Histories();
        }
        historiesList.add(history);

        if (historiesList.size() > historiesMaxSize) {
            historiesList = historiesList.subList(0, historiesMaxSize);
        }

        histories.setHistories(historiesList);

        mJsonCacheUtil.saveCache(KEY_HISTORY, histories);
    }


    @Override
    public void doSearch(String keyword) {

        // safe check
        if (TextUtils.isEmpty(keyword)) {
            return;
        }

        saveHistory(keyword);
        this.mCurrentKeyword = keyword;

        if (mViewCallback == null) {
            ToastUtils.showToast("must register a callback for SearchPresenter");
            return;
        }

        Call<SearchResult> task = mApi.doSearch(mCurrentPage, keyword);

        task.enqueue(new Callback<SearchResult>() {
            @Override
            public void onResponse(@NonNull Call<SearchResult> call, @NonNull Response<SearchResult> response) {
                if (response.code() == HttpURLConnection.HTTP_OK) {

                    try {
                        assert response.body() != null;
                        if (response.body().getData().getTbk_dg_material_optional_response().getResult_list().getMap_data().size() != 0) {
                            mViewCallback.onSearchSuccess(response.body().getData().getTbk_dg_material_optional_response().getResult_list().getMap_data());
                        } else {
                            mViewCallback.onEmpty();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        mViewCallback.onEmpty();
                    }
                } else {
                    mViewCallback.onNetworkError();
                }
            }

            @Override
            public void onFailure(@NonNull Call<SearchResult> call, @NonNull Throwable t) {

                mViewCallback.onNetworkError();
            }
        });
    }

    @Override
    public void research() {
        if (mCurrentKeyword != null && !mIsLoadMoreFlag) {
            doSearch(mCurrentKeyword);
        } else {
            if (mViewCallback != null) {
                mViewCallback.onEmpty();
            }
        }
    }

    @Override
    public void loaderMore() {
        if (mViewCallback == null) {
            ToastUtils.showToast("must register a callback for SearchPresenter");
            return;
        }

        if (mCurrentKeyword != null) {
            mIsLoadMoreFlag = true;
            mCurrentPage++;

            Call<SearchResult> task = mApi.doSearch(mCurrentPage, mCurrentKeyword);

            task.enqueue(new Callback<SearchResult>() {
                @Override
                public void onResponse(@NonNull Call<SearchResult> call, @NonNull Response<SearchResult> response) {
                    if (response.code() == HttpURLConnection.HTTP_OK) {

                        assert response.body() != null;
                        if (response.body().getData().getTbk_dg_material_optional_response().getResult_list().getMap_data().size() != 0) {
                            mViewCallback.onMoreLoaded(response.body().getData().getTbk_dg_material_optional_response().getResult_list().getMap_data());

                        } else {
                            mViewCallback.onMoreLoadedEmpty();
                            mCurrentPage--;
                        }
                    } else {
                        mViewCallback.onMoreLoaderError();
                        mCurrentPage--;
                    }

                    mIsLoadMoreFlag = false;
                }

                @Override
                public void onFailure(@NonNull Call<SearchResult> call, @NonNull Throwable t) {
                    mCurrentPage--;
                    mIsLoadMoreFlag = false;
                    mViewCallback.onMoreLoaderError();
                }
            });
        } else {
            mViewCallback.onMoreLoadedEmpty();
        }

    }

    @Override
    public void getRecommendWords() {
        if (mViewCallback == null) {
            ToastUtils.showToast("must register a callback for SearchPresenter");
            return;
        }

        Call<SearchRecommend> task = mApi.getRecommendWords();

        task.enqueue(new Callback<SearchRecommend>() {
            @Override
            public void onResponse(@NonNull Call<SearchRecommend> call, @NonNull Response<SearchRecommend> response) {

                if (response.code() == HttpURLConnection.HTTP_OK) {
                    // detail result
                    if (response.body() != null && response.body().getData().size() != 0) {
                        mViewCallback.onRecommendWordsLoaded(response.body().getData());
                    } else {
                        mViewCallback.onEmpty();
                    }
                } else {
                    mViewCallback.onNetworkError();
                }
            }

            @Override
            public void onFailure(@NonNull Call<SearchRecommend> call, @NonNull Throwable t) {
                mViewCallback.onNetworkError();
            }
        });
    }

    @Override
    public void registerViewCallback(ISearchViewCallback callback) {
        mViewCallback = callback;
    }

    @Override
    public void unRegisterViewCallback(ISearchViewCallback callback) {
        mViewCallback = null;
    }
}
